import json
import os.path
import winreg
import requests
from selenium.common import WebDriverException, NoSuchElementException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
import time
import datetime
from selenium import webdriver
import zipfile as zp


def share_browser():
    # 初始化
    chrome_options = Options()
    # chrome_options.add_argument('--headless')         # 用来决定浏览器的打开与否
    chrome_options.add_argument(" log-level=3")
    chrome_options.add_argument("--disable-gpu")
    path = r'C:\Program Files\Google\Chrome\Application\chrome.exe'  # 放置谷歌浏览器的位置.exe
    chrome_options.binary_location = path
    brower = webdriver.Chrome(chrome_options=chrome_options)
    return brower


# 报错之后chrome 下载
def getChromeWebdriver():
    # 向驱动商店发送请求
    url = "https://registry.npmmirror.com/-/binary/chromedriver/"
    # 请求头信息的定制
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
    }
    # 模拟浏览器向服务器发送请求
    response = requests.get(url=url, headers=headers)
    # 将获取的页面数据转换为JSON格式
    b = json.loads(response.text)
    # 将页面中的chrome版本信息存入列表中，再前chrome的前三位存入列表中，便于寻找下标。
    browserVersionindex = []
    browserVersion = []
    for i in b:
        browserVersionindex.append(i["name"][0:3])
        browserVersion.append(i["name"])
    # 获取当前主机的谷歌版本
    FullChromeVersion = winreg.QueryValueEx(winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
                                                           'SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Google Chrome'),
                                            'DisplayVersion')[0]
    ChromeVersion = FullChromeVersion.split('.')[0]
    # 在获取的页面数据查询是否具有对应的驱动
    if ChromeVersion in browserVersionindex:
        index = browserVersionindex.index(ChromeVersion)
        version = browserVersion[index].split("/")[0]
    # 下载指定版本的驱动
    url = f"https://cdn.npmmirror.com/binaries/chromedriver/{version}/chromedriver_win32.zip"
    # 请求头信息的定制
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
    }
    # 获取数据，并存入本地
    response = requests.get(url=url, headers=headers)
    with open("chromedriver_win32.zip", "wb") as fp:
        fp.write(response.content)
    # 将所下载的压缩包下载
    with zp.ZipFile("chromedriver_win32.zip", 'r') as zfiles:
        for file in zfiles.namelist():
            zfiles.extract(file)
    # 删除没有用的压缩包
    os.remove("chromedriver_win32.zip")


# 选择起始小节，获取数据
def chooseClassNum(beginNum, endNum):
    brower.find_element(By.XPATH, "//input[@title='起始小节']").clear()
    brower.find_element(By.XPATH, "//input[@title='起始小节']").send_keys(str(beginNum))
    brower.find_element(By.XPATH, "//input[@title='结束小节']").clear()
    brower.find_element(By.XPATH, "//input[@title='结束小节']").send_keys(str(endNum))
    import time
    time.sleep(1)
    brower.find_element(By.XPATH, "//tr[@class='thead']/td/input[@value='查询']").click()
    time.sleep(1)
    # 获取到需要的数据
    a = brower.find_elements(By.XPATH, "//tbody[@id='grid15320024301_data']/tr")
    classrooms = []
    for i in a:
        c = i.find_elements(By.TAG_NAME, 'td')[1]
        c_text = c.text[3:]
        classrooms.append(c_text)
    return classrooms


def data_format_mod(classrooms):
    classroomsMeetRequire=[]
    classroomsEndRequire=[]
    for classroom in classrooms:
        if len(classroom)==3:
            classroomsMeetRequire.append(int(classroom))
    classroomsMeetRequire.sort()
    for classroomEnd in classroomsMeetRequire:
        classroomEnd='G'+str(classroomEnd)
        classroomsEndRequire.append(classroomEnd)
    return classroomsEndRequire


if __name__ == '__main__':
    try:
        brower = share_browser()
    except WebDriverException:
        getChromeWebdriver()
        brower=share_browser()
    brower.get(
        'http://vpn.neuq.edu.cn/http/77726476706e69737468656265737421f9f352d229357d41300d8db9d6562d/authserver/login?service=http%3A%2F%2Fvpn.neuq.edu.cn%2Flogin%3Fcas_login%3Dtrue')
    time.sleep(1)
    # 输入登录信息 首先检查本地是否具有登录文本login.text 如果有的话直接读入里面的信息，否则就让用户输入
    if os.path.exists("login.text"):
        with open("login.text", 'r', encoding="utf-8") as fp:
            login_content = fp.read()
        number=login_content.split("\n")[0].split(":")[1]
        password=login_content.split("\n")[1].split(":")[1]
    else:
        number = input("请输入你的学号：")
        password = input("请输入你的密码：")
    brower.find_element(By.ID, 'username').send_keys(number)
    brower.find_element(By.ID, 'password').send_keys(password)
    brower.find_element(By.XPATH, "//button[@class='submitBtn']").click()
    time.sleep(1)
    try:
        brower.find_element(By.XPATH, "//p[@title='教务系统(统一认证入口)']").click()
    except NoSuchElementException:
        print("账号或者密码有误，请重新运行")
        brower.quit()
    time.sleep(1)
    all_handles = brower.window_handles
    for handle in all_handles:
        brower.switch_to.window(handle)
        if "门户" not in brower.title:
            break
    time.sleep(1)
    js = "document.documentElement.scrollTop=100000"
    brower.execute_script(js)
    time.sleep(1)
    brower.find_element(By.XPATH, "//table[@id='mainTable']/tbody/tr/td[1]//ul/li[3]").click()
    time.sleep(1)
    brower.find_element(By.XPATH, "//a[text()='  空闲教室查询']").click()
    time.sleep(1)
    teachBuild = brower.find_element(By.XPATH, "//select[@id='building']")
    # 获取到教学楼的标签
    building = Select(teachBuild)
    # 获取填写开始日期的input标签并填写内容
    building.select_by_value("1")
    # 获取一日的日差
    daily_rate=datetime.timedelta(days=1)
    # 获取今日的年月日再加上一天的时差得到明天的年月日
    time=datetime.datetime.now()+daily_rate
    date=time.strftime("%Y-%m-%d")
    # 传入明日的年月日
    js1="document.getElementById('dateBegin').value='"+date+"'"
    brower.execute_script(js1)
    wd = brower.find_element(By.XPATH, "//iframe[@frameborder='0']")
    # 转入日历所在的iframe
    brower.switch_to.frame(wd)
    brower.switch_to.default_content()
    # 获取填写结束日期的input标签并填写内容
    js2 = "document.getElementById('dateEnd').value='"+date+"'"
    brower.execute_script(js2)
    brower.switch_to.frame(wd)
    # 放回到之前的iframe
    brower.switch_to.default_content()
    # 判断classroomFree.txt是否存在如何存在先删除
    if os.path.exists('classroomsFree.txt'):
        os.remove('classroomsFree.txt')
    # 向目标txt文件中加入日期
    with open('classroomsFree.txt', 'a', encoding='utf-8') as fp:
        fp.write("日期：")
        fp.write(date)
        fp.write("\n")
    # 使用循环遍历1-2  3-4  5-6 7-8 的小节的课表
    for i in range(1, 6):
        # 输入你想要查询的开始小节时间和结束小节时间（明天的）
        beginNum =str(2*i-1)
        endNum = str(2*i)
        # 调用chooseClassNum函数，获取对应的空闲教室情况
        classrooms = chooseClassNum(beginNum, endNum)
        # 调用data_format_mod对得到的数据进行取舍、排序、格式修正。
        classrooms_end=data_format_mod(classrooms)
        with open('classroomsFree.txt', 'a', encoding='utf-8') as fp:
            fp.write('第{}小节-{}小节的空教室为：'.format(2*i-1, 2*i))
            fp.write('  '.join(classrooms_end))
            fp.write('\n')
    # 单独获取第1-8小节的空闲教室情况
    beginNum = str(1)
    endNum = str(8)
    # 调用chooseClassNum函数，获取对应的空闲教室情况
    classrooms = chooseClassNum(beginNum, endNum)
    # 调用data_format_mod对得到的数据进行取舍、排序、格式修正。
    classrooms_end = data_format_mod(classrooms)
    with open('classroomsFree.txt', 'a', encoding='utf-8') as fp:
        fp.write('第1小节-8小节的空教室为：')
        fp.write('  '.join(classrooms_end))
        fp.write('\n')
    # 将正确的账号密码保存：
    with open("login.text", 'w', encoding="utf-8") as fp:
        fp.write("学号为:" + str(number) + "\n" + "密码为:" + str(password))
    brower.quit()
